home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / GX Libraries / ArcLibrary.c next >
Encoding:
C/C++ Source or Header  |  1995-04-07  |  5.1 KB  |  167 lines  |  [TEXT/MPS ]

  1.  
  2. /*
  3.     File:        ArcLibrary.c
  4.  
  5.     Contains:    graphics libraries - arc and wedge functions
  6.  
  7.     Written by:    Mike Reed
  8.  
  9.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.          <3>      4/7/95    jtd        changed 'fract' to 'Fract'
  14.          <2>      1/9/95    JD        changed 'boolean' to 'Boolean'
  15.          <1>      1/9/95    JD        First checked in.
  16.     Previous History:
  17.     
  18.         Sean Parent     - fixed bug (first pt off gxCurve)
  19.                         - added code to obey sweep direction (negative is counter-clockwise)
  20. */
  21.  
  22. #include "GraphicsLibraries.h"
  23.  
  24. /*
  25.   * Same as the QD call, but takes fixed parameters.  The wedge boolean is set to false for FrameArc
  26.   * and to true for everything else.
  27.   */
  28.  
  29. #define kFracCos45over2     0x3B20D79E
  30. #define kMaxArcPoints       13
  31.  
  32. typedef struct {
  33.     long count;
  34.     long ctrBits;
  35.     gxPoint data[kMaxArcPoints];      /* only need up to 12 + 1 for center of wedge */
  36. } tmpArcPathType;
  37.  
  38.  
  39. /*
  40.   * Used by NewArc and SetArc, it sets 'aPathPtr'
  41.   * (a tmpArcPathType) to the appropriate
  42.   * wedge gxShape.
  43.   */
  44. static void SetArcData(const gxRectangle *r, Fixed startAng, Fixed sweep, Boolean wedge, tmpArcPathType *aPathPtr)
  45. {
  46.     register long *ptWalker;
  47.  
  48.     aPathPtr->count = 0;
  49.     aPathPtr->ctrBits = 0;
  50.     {
  51.         register            Fixed   halfWidth   = (r->right - r->left + 1) >> 1;
  52.         register            Fixed   halfHeight  = (r->top - r->bottom + 1) >> 1;
  53.         register            Fixed   sweepAng = sweep;
  54.         register            Fixed   midPointAng;
  55.         register unsigned   long    ctrBitMask = 0x40000000U;
  56.         register            short   i;
  57.                             Fixed   cosineValue;
  58.                             Fixed   incrementAng;
  59.                             Fixed   halfIncrementAng;
  60.  
  61.         if (sweep < 0) incrementAng = ff(-45);
  62.         else incrementAng = ff(45);
  63.         halfIncrementAng = incrementAng >> 1;
  64.  
  65.         midPointAng = startAng + halfIncrementAng;
  66.     /*
  67.       * Always set the first gxPoint
  68.       */
  69.         ptWalker = &aPathPtr->data[0].x;
  70.         *ptWalker++ = FractMultiply(FractSineCosine(startAng, &cosineValue), halfWidth);
  71.         *ptWalker++ = FractMultiply(cosineValue, halfHeight);
  72.  
  73.         for (i = FixedToInt(sweepAng) / FixedToInt(incrementAng) - 1; i >= 0; i--) {
  74.             *ptWalker++ = MultiplyDivide(halfWidth, FractSineCosine(midPointAng, &cosineValue), kFracCos45over2);
  75.             *ptWalker++ = MultiplyDivide(halfHeight, cosineValue, kFracCos45over2);
  76.             aPathPtr->ctrBits |= ctrBitMask;
  77.             midPointAng += incrementAng;
  78.             ctrBitMask >>= 1;
  79.             sweepAng -= incrementAng;
  80.         }
  81.     /*
  82.       * Finish with a short parabola if not on a 45 degree multiple
  83.       */
  84.         if (sweepAng != 0)
  85.         {   Fract lamda;
  86.             
  87.             sweepAng >>= 1;
  88.             FractSineCosine(sweepAng, &lamda);
  89.             midPointAng -= halfIncrementAng; /* reset to end of 45 degree segments */
  90.     /*
  91.       * Begin the short piece if we added OFF points earlier
  92.       */
  93.             if (ptWalker - &aPathPtr->data[0].x > 2) {
  94.                 *ptWalker++ = FractMultiply(FractSineCosine(midPointAng, &cosineValue), halfWidth);
  95.                 *ptWalker++ = FractMultiply(cosineValue, halfHeight);
  96.                 ctrBitMask >>= 1;
  97.             }
  98.             *ptWalker++ = MultiplyDivide(halfWidth, FractSineCosine(midPointAng + sweepAng, &cosineValue), lamda);
  99.             *ptWalker++ = MultiplyDivide(halfHeight, cosineValue, lamda);
  100.             aPathPtr->ctrBits |= ctrBitMask;
  101.         }
  102.     /*
  103.       * Finish with the final ON gxPoint
  104.       */
  105.         *ptWalker++ = FractMultiply(FractSineCosine(startAng + sweep, &cosineValue), halfWidth);
  106.         *ptWalker++ = FractMultiply(cosineValue, halfHeight);
  107.     }
  108. /*
  109.   * Time to make the gxPath
  110.   */
  111.     if (wedge) {
  112.         *ptWalker++ = 0;
  113.         *ptWalker++ = 0;
  114.     }
  115.     {   register Fixed centerX  = (r->right + r->left + 1) >> 1;
  116.         register Fixed centerY  = (r->bottom + r->top + 1) >> 1;
  117.         register short counter = (ptWalker - &aPathPtr->data[0].x) >> 1;
  118.         
  119.         aPathPtr->count = counter;
  120.         for  (counter -= 1; counter >= 0; counter--) {  
  121.             *--ptWalker += centerY;
  122.             *--ptWalker += centerX;
  123.         }
  124.     }
  125. }
  126.  
  127.  
  128. gxShape NewArc(const gxRectangle *r, Fixed startAng, Fixed sweep, Boolean wedge)
  129. {
  130.     tmpArcPathType aPath;
  131.     gxShape arcShape;
  132.     
  133.     NilParamReturnNil(r);
  134.     if ((sweep >= ff(360)) || (sweep <= ff(-360)))
  135.         return NewOval(r);
  136.  
  137.     SetArcData(r,startAng,sweep,wedge,&aPath);
  138.     arcShape = NewPath((gxPath *) &aPath);
  139.     
  140.     GXSetShapeFill(arcShape, wedge ? gxSolidFill : gxFrameFill);
  141.     return arcShape;
  142. }
  143.  
  144. void SetArc(gxShape sh, const gxRectangle *r, Fixed startAng, Fixed sweep, Boolean wedge)
  145. {
  146.     tmpArcPathType aPath;
  147.  
  148.     NilParamReturn(r);
  149.     
  150.     if ((sweep >= ff(360)) || (sweep <= ff(-360))) SetOval(sh,r);
  151.     else {
  152.         SetArcData(r,startAng,sweep,wedge,&aPath);
  153.         SetPath(sh, 0, (gxPath *) &aPath);
  154.     }
  155. }
  156.  
  157.  
  158. void DrawArc(const gxRectangle *r, Fixed startAng, Fixed sweep, Boolean wedge)
  159. {
  160.     gxShape arcShape;
  161.     
  162.     NilParamReturn(r);
  163.     arcShape = NewArc(r, startAng, sweep, wedge);
  164.     GXDrawShape(arcShape);
  165.     GXDisposeShape(arcShape);
  166. }
  167.